﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace OneSchema
{
    public class FDSet : HashSet<FD>
    {

        public AttributeSet ComputeAttributeClosure(AttributeSet attributes)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Remove trivial FDs and return the FDs removed.
        /// </summary>
        public List<FD> RemoveTrivialFDs()
        {
            List<FD> trivialFDs = new List<FD>();

            // Collect all trivial FDs
            foreach (FD fd in this)
                if (fd.IsTrivial()) trivialFDs.Add(fd);

            // Remove all trival fds
            foreach (FD fd in trivialFDs)
                this.Remove(fd);

            return trivialFDs;
        }

        public AttributeSet GetUsedAttributes()
        {
            AttributeSet usedAttr = new AttributeSet();
            foreach (FD fd in this)
                usedAttr.UnionWith(fd.GetUsedAttributes());

            return usedAttr;
        }

        public AttributeSet GetUnusedAttributes()
        {
            AttributeSet usedAttr = GetUsedAttributes();
            usedAttr.Complement();
            return usedAttr;
        }

        public AttributeSet FindAttributeClosure(AttributeSet attr)
        {
            bool changeFlag = true;
            AttributeSet closure = new AttributeSet(attr);

            while (changeFlag == true)
            {
                changeFlag = false;
                foreach (FD fd in this)
                {
                    if (fd.LHS.IsSubsetOf(closure) && !fd.RHS.IsSubsetOf(closure))
                    {
                        changeFlag = true;
                        closure.UnionWith(fd.RHS);
                    }
                }
            }

            return closure;
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder("{");

            foreach (FD fd in this)
            {
                sb.Append(fd.ToString());
                sb.Append(",");
            }

            //remove last comma
            if (sb[sb.Length - 1] == ',')
                sb.Remove(sb.Length - 1, 1);

            sb.Append("}");
            return sb.ToString();
        }
    }
}
